#include "visbasecontainer.h"
//#include "visbaseelement.h"
//#include "visbasewidget.h"
//#include "SageVis/sagevis.h*/"

//#include "visbaseelement.h"
#include "SageVis/sagevis.h"
#include "visbasewidget.h"
#include "SageVis/VisBaseClasses/visbaselayout.h"


VisBaseContainer::VisBaseContainer( QPointer<SageVis> sageVisPointer, QPointer<VisBaseWidget> parentWidget, QGraphicsItem *parent ) :
    VisBaseElement( sageVisPointer, parentWidget, parent ) //sageVisPointer( sageVisPointer ), parentWidget(parentWidget), QGraphicsWidget(parent)
{
    containerBoundingRect.setCoords(0, 0, 0, 0);//I dont think I am using this right now

    //this is the mechanism by which vis base containers run a layout in a separate thread- their parent's thread
    //  once the layout is created, and all genome elements are added, this layout is passed to the parent widget
    //  and the layout is run on the separate thread.
    connect( this, SIGNAL(runLayoutSignal(VisBaseLayout*)), parentWidget, SLOT( runLayoutSlot(VisBaseLayout*)));
}

//VisBaseContainer::~VisBaseContainer()
//{
//    if( layout != 0 )
//        delete layout;
//}

//------------------------------SLOTS----------------------------------------------
void VisBaseContainer::advance()
{

}

void VisBaseContainer::callUpdate()
{
    update();
}

void VisBaseContainer::recomputeLayoutSlot()
{
    qDebug() << "recompute layout" << endl;
    layoutElements();
}

void VisBaseContainer::moveLayoutBackToThisThread()
{
    //if( layout ) //should always be true if slot called properly
        //layout->moveToThread(this->thread());
}

//------------------------------ADD ELEMENTS---------------------------------------
void VisBaseContainer::addElement(QPointer<VisBaseElement> e)
{
    elements << e;
    connect( e, SIGNAL(recomputeLayoutSignal()), this, SLOT(recomputeLayoutSlot()) );//ensure that if child can signal parent to layout again
                                                                                    //in the event of a change in height
}

//-------------------CONNECT ELEMENTS AND CONTAINER-------------------------------
void VisBaseContainer::connectContainerToElements(int type)
{
    for(int i = 0 ; i < elements.size(); i++ )
    {
        this->forgeConnection(elements[i], type);
    }
}

void VisBaseContainer::connectElementsToContainer(int type)
{

    for(int i = 0 ; i < elements.size(); i++ )
    {
        elements[i]->forgeConnection(this, type);
    }
}

void VisBaseContainer::connectTwoWayElementsToContainer(int type)
{
    for(int i = 0 ; i < elements.size(); i++ )
    {
        forgeConnection(this, elements[i], type);
    }
}

//-------------------SET HEIGHT, WIDTH, XPos, YPos---------------------------------
    //--------FLOAT----------------------------------------------------------------
//give elements uniform width
void VisBaseContainer::setWidthOfElements( float w )
{
    for(int i = 0; i < elements.size(); i++ )
    {
        elements[i]->setWidth(w);
    }
}

//give elements uniform height
void VisBaseContainer::setHeightOfElements( float h )
{
    for(int i = 0; i < elements.size(); i++ )
    {
        elements[i]->setHeight(h);
    }
}

void VisBaseContainer::setWidthAndHeightOfElements(float w, float h)
{
    for(int i = 0; i < elements.size(); i++ )
    {
        elements[i]->setHeight(h);
        elements[i]->setWidth(w);
    }
}

//line up vertically
void VisBaseContainer::setXPosOfElements( float xPos )
{
    for(int i = 0; i < elements.size(); i++ )
    {
        elements[i]->setPos( xPos, elements[i]->pos().y() );
    }
}

//line up horizontally
void VisBaseContainer::setYPosOfElements( float yPos )
{
    for(int i = 0; i < elements.size(); i++ )
    {
        elements[i]->setPos( elements[i]->pos().x(), yPos );
    }
}

//stacked atop each other
void VisBaseContainer::setPosOfElements( float x, float y )
{
    for(int i = 0; i < elements.size(); i++ )
    {
        elements[i]->setPos( x, y );
    }
}

    //--------INT----------------------------------------------------------------
//give elements uniform width
void VisBaseContainer::setWidthOfElements( int w )
{
    setWidthOfElements( (float) w);
}

//give elements uniform height
void VisBaseContainer::setHeightOfElements( int h )
{
    setHeightOfElements( (float) h);
}

void VisBaseContainer::setWidthAndHeightOfElements(int w, int h )
{
    setWidthAndHeightOfElements( (float) w, (float) h);
}

//line up vertically
void VisBaseContainer::setXPosOfElements( int xPos )
{
    setXPosOfElements( (float) xPos );
}

//line up horizontally
void VisBaseContainer::setYPosOfElements( int yPos )
{
    setYPosOfElements( (float) yPos );
}

//stacked atop each other
void VisBaseContainer::setPosOfElements( int x, int y )
{
    setPosOfElements( (float) x, (float) y );
}
//-------------------GET MAX WIDTH ---------------------------------
//find the maxWidth of elements
float VisBaseContainer::getMaxElementWidth()
{
    maxElementWidth = -1.0;
    for(int i = 0; i < elements.size(); i++)
    {
        if( elements[i]->boundingRect().width() > maxElementWidth )
            maxElementWidth = elements[i]->boundingRect().width() ;
    }
    return maxElementWidth;
}

//-------------------------------SIZE AND SHAPE-----------------------------------
//void VisBaseContainer::setGeometry(const QRectF &geom)
//{
//    prepareGeometryChange();
//    QGraphicsWidget::setGeometry(geom);
//    setPos(geom.topLeft());
//}

//void VisBaseContainer::setGeometry(qreal x, qreal y, qreal w, qreal h)
//{
//    setGeometry(QRect(x, y, w, h));
//}

//QRectF VisBaseContainer::boundingRect() const
//{
//    return QRectF(QPointF(0,0), geometry().size());
//}


//QPainterPath VisBaseContainer::shape() const
//{
//    QPainterPath path;
//    path.addRect(boundingRect());
//    return path;
//}

//---------------------------------LAYOUT--------------------------------------------
void VisBaseContainer::setLayout(VisBaseLayout *l)
{
    layout = l;
    layout->addElements(elements);
}

void VisBaseContainer::layoutElements()
{
    emit( runLayoutSignal(layout) );
}

void VisBaseContainer::layoutElements(VisBaseLayout* layout)
{
    layout->addElements(elements);
    emit( runLayoutSignal(layout) );
}

void VisBaseContainer::layoutElementsNonThreaded()
{
    layout->process();
    update();
}

void VisBaseContainer::layoutElementsNonThreaded(VisBaseLayout* layout)
{
    layout->addElements(elements);
    layout->process();
    update();
}




